/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file ohos_transport.c
 * @brief OHOS传输层实现
 */
#include <mutex>
#include "v1_1/infc_interface.h"
#include "idevmgr_hdi.h"
#include "hdf_remote_service.h"
#include "servmgr_hdi.h"

#include "ohos_transport.h"
#include "nfc_transport_api.h"
#include "nfc_log_api.h"
#include "nfc_osi_api.h"
#include "osi_config_parser.h"

#define KEY_OFFSET (2)
#define IOCTL_RSP_BUF_SIZE 256

tNFC_STATUS is_check_firmware_completed = NFC_STATUS_FAILED;

static tMUTEX check_firmware_lock = MUTEX_INIT_VAL("check_firmware");

using namespace std;
//using namespace OHOS::HDI::NFC;
//using base::StringPrintf;
using OHOS::HDI::Nfc::V1_0::NfcStatus;
using OHOS::HDI::Nfc::V1_0::NfcEvent;
using OHOS::HDI::Nfc::V1_0::INfcCallback;
using OHOS::HDI::Nfc::V1_1::VendorProtocalDiscoveryCfg;
using OHOS::HDI::Nfc::V1_1::NfcVendorConfig;
using INfcV1_1 = OHOS::HDI::Nfc::V1_1::INfcInterface;

OHOS::sptr<INfcV1_1> mHal = nullptr;
OHOS::sptr<INfcCallback> mCallback = nullptr;

HdfRemoteService *g_hdiService = nullptr;
constexpr const char *NFC_HDI_NAME = "nfc_interface_service";
static std::mutex g_instanceMutex;
std::unique_ptr<TransportAdaptation> TransportAdaptation::instance = nullptr;

class NfcClientCallback : public INfcCallback {
    public:
    NfcClientCallback(tNFC_EVENT_CALLBACK eventCallback,
            tNFC_DATA_CALLBACK dataCallback)
    {
        mEventCallback = eventCallback;
        mDataCallback = dataCallback;
    };
    virtual ~NfcClientCallback() = default;

    int32_t OnData(const std::vector<uint8_t>& data)
    {
        if (mDataCallback != nullptr && !data.empty()) {
            mDataCallback(data.size(), (uint8_t *)&data[0]);
        }
        return HDF_SUCCESS;
    }

    int32_t OnEvent(NfcEvent event, NfcStatus status)
    {
        if (mEventCallback != nullptr) {
            mEventCallback(static_cast<tNFC_EVENT>(event), static_cast<tNFC_STATUS>(status));
        }
        return HDF_SUCCESS;
    }

    private:
        tNFC_EVENT_CALLBACK mEventCallback;
        tNFC_DATA_CALLBACK mDataCallback;
};

TransportAdaptation& TransportAdaptation::GetInstance()
{
    std::lock_guard<std::mutex> lock(g_instanceMutex);
    if (!instance) {
        instance.reset(new TransportAdaptation());
        instance->InitializeHalService();
    }
    return *instance;
}

tNFC_STATUS tp_open(tNFC_EVENT_CALLBACK event_cb, tNFC_DATA_CALLBACK data_cb)
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().Open(event_cb, data_cb);
}

tNFC_STATUS tp_close(tNFC_CLOSE_TYPE type)
{
    NFCLOG_I("Enter type = %d", type);
    return TransportAdaptation::GetInstance().Close(type);
}

tNFC_STATUS tp_core_init()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().CoreInitialized();
}

tNFC_STATUS tp_factory_reset()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().FactoryReset();
}

tNFC_STATUS tp_check_firmware()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().CheckFirmware();
}

tNFC_STATUS tp_ioctl(long arg, uint8_t *p_data)
{
    if (mHal == nullptr || p_data == nullptr) {
        NFCLOG_E("mHal or p_data is null");
        return NFC_STATUS_INVALID_PARAM;
    }

    NFCLOG_I("Enter, arg = %ld", arg);
    uint8_t dataLen = 128;
    uint8_t outDataStartIdx = 128;
    std::vector<uint8_t> inData(dataLen, 0);
    std::vector<uint8_t> outData(dataLen, 0);
    if (!osi_memcpy(&(inData[0]), dataLen, p_data, dataLen)) {
        NFCLOG_E("memcpy inData failed");
        return NFC_STATUS_FAILED;
    }

    NfcStatus status = NfcStatus::FAILED;
    mHal->IoctlWithResponse((OHOS::HDI::Nfc::V1_0::NfcCommand)arg, inData, outData, status);
    NFCLOG_I("status = %d", status);
    if (status == NfcStatus::OK) {
        uint8_t *pTemp = p_data;
        if (!osi_memcpy(&(pTemp[outDataStartIdx]), dataLen, static_cast<void *>(&(outData[0])), dataLen)) {
            NFCLOG_E("memcpy outData failed");
            return NFC_STATUS_FAILED;
        }
        return NFC_STATUS_OK;
    }

    NFCLOG_E("Failed");
    return NFC_STATUS_FAILED;
}


tNFC_STATUS tp_get_config(void *data)
{
    OSI_CHK_PARAM_INVALID(!data, return NFC_STATUS_INVALID_PARAM);
    tNFC_CONFIG_MANAGER *cm = static_cast<tNFC_CONFIG_MANAGER*>(data);
    NFCLOG_I("Enter");
    tNFC_STATUS status = TransportAdaptation::GetInstance().GetConfig(cm);
    if (status != NFC_STATUS_OK) {
        NFCLOG_E("get vendor config failed");
        return status;
    }
    status = TransportAdaptation::GetInstance().GetExtConfig(cm);
    if (status != NFC_STATUS_OK) {
        NFCLOG_E("get vendor config ext failed");
        return status;
    }
    return status;
}

tNFC_STATUS tp_power_cycle()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().PowerCycle();
}

tNFC_STATUS tp_pre_discovery()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().PreDiscovery();
}

tNFC_STATUS tp_write(const uint8_t* p_data, uint16_t dataLen)
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().Write(p_data, dataLen);
}

tNFC_STATUS tp_set_transit_config(const char* value)
{
    NFCLOG_I("Enter");
    return NFC_STATUS_FAILED;
}

tNFC_STATUS tp_is_config_modified()
{
    NFCLOG_I("Enter");
    return TransportAdaptation::GetInstance().IsConfigModified() ? NFC_STATUS_OK : NFC_STATUS_FAILED;
}

TransportAdaptation::TransportAdaptation()
{
    if (osi_mutex_init(&check_firmware_lock) != NFC_STATUS_OK) {
        NFCLOG_E("init check_firmware_lock failed");
    }
    NFCLOG_I("TransportAdaptation instance created");
}

TransportAdaptation::~TransportAdaptation()
{
    osi_mutex_deinit(&check_firmware_lock);
    instance = nullptr;
    NFCLOG_I("TransportAdaptation instance destroyed");
}

tNFC_STATUS TransportAdaptation::Open(tNFC_EVENT_CALLBACK event_cb, tNFC_DATA_CALLBACK data_cb)
{
    if (mHal != nullptr) {
        mCallback = OHOS::sptr<NfcClientCallback>(new NfcClientCallback(event_cb, data_cb));
        NfcStatus status = NfcStatus::FAILED;
        int result = mHal->Open(mCallback, status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Succeeded with INfcHidl");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

tNFC_STATUS TransportAdaptation::Close(tNFC_CLOSE_TYPE type)
{
    NfcStatus halStatus = NfcStatus::FAILED;
    int hdfResult = HDF_FAILURE;
    tNFC_STATUS retStatus = NFC_STATUS_FAILED;

    if (mHal == nullptr) {
        NFCLOG_E("NFC HAL not initialized");
        goto cleanup;
    }

    if (type == NFC_CLOSE_TYPE_DISABLE) {
        hdfResult = mHal->Close(halStatus);
    } else if (type == NFC_CLOSE_TYPE_HOST_SWITCHED_OFF) {
        hdfResult = mHal->Shutdown(halStatus);
    } else {
        NFCLOG_E("Invalid close type: %d", static_cast<int>(type));
        retStatus = NFC_STATUS_FAILED;
        goto cleanup;
    }

    if (hdfResult == HDF_SUCCESS && halStatus == NfcStatus::OK) {
        NFCLOG_I("HAL close succeeded");
        retStatus = NFC_STATUS_OK;
    } else {
        NFCLOG_E("HAL close failed. HDF error: %d, HAL status: %d",
            hdfResult, static_cast<int>(halStatus));
        retStatus = NFC_STATUS_FAILED;
    }

cleanup:
    Finalize();
    return retStatus;
}

tNFC_STATUS TransportAdaptation::CoreInitialized()
{
    if (mHal != nullptr) {
        NfcStatus status = NfcStatus::FAILED;
        // 创建一个包含静态空字节的 std::vector
        static uint8_t emptyData = 0xFF;
        std::vector<uint8_t> data(1, emptyData);  // 初始化大小为1，值为0xFF

        int result = mHal->CoreInitialized(data, status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Succeeded with INfcHidl");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

tNFC_STATUS TransportAdaptation::FactoryReset()
{
    if (mHal != nullptr) {
        NfcStatus status = NfcStatus::FAILED;
        int result = mHal->DoFactoryReset(status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Succeeded with INfcHidl");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

tNFC_STATUS TransportAdaptation::CheckFirmware()
{
    tNFC_STATUS ret = NFC_STATUS_OK;
    if (osi_mutex_lock(&check_firmware_lock) != NFC_STATUS_OK) {
        NFCLOG_E("get check_firmware_lock failed");
        return NFC_STATUS_FAILED;
    }
    is_check_firmware_completed = NFC_STATUS_FAILED;
    if (tp_open(hal_check_firmware_callback, hal_check_firmware_data_callback) != NFC_STATUS_OK) {
        NFCLOG_E("tp_open failed");
        ret = NFC_STATUS_FAILED;
        goto mutex_unlock;
    }
    if (osi_mutex_wait_forever(&check_firmware_lock) != NFC_STATUS_OK) {
        NFCLOG_E("wait failed");
        ret = NFC_STATUS_FAILED;
        goto mutex_unlock;
    }
    if (tp_close(NFC_CLOSE_TYPE_DISABLE) != NFC_STATUS_OK) {
        NFCLOG_E("tp_close failed");
        ret = NFC_STATUS_FAILED;
        goto mutex_unlock;
    }

    ret = is_check_firmware_completed;

mutex_unlock:
    osi_mutex_unlock(&check_firmware_lock);

    return ret;
}

static bool PrepareDataBuffer(uint8_t* data, size_t dataLen, tNFC_CF_PARAM* item)
{
    if (!item->key) {
        NFCLOG_E("Item key is null");
        return false;
    }
    // 清空数据缓冲区
    osi_memset(data, IOCTL_RSP_BUF_SIZE, 0, IOCTL_RSP_BUF_SIZE);
    data[0] = item->type;
    size_t keyLen = strlen(item->key);
    if (keyLen > (dataLen - KEY_OFFSET)) {
        NFCLOG_E("Key length exceeds buffer size: %s", item->key);
        return false;
    }

    data[1] = static_cast<uint8_t>(keyLen);
    if (!osi_strncpy((char *)data + KEY_OFFSET, dataLen - KEY_OFFSET, item->key, keyLen + 1)) {
        NFCLOG_E("Failed to copy key: %s", item->key);
        return false;
    }

    return true;
}

// 辅助函数：验证数据长度
static bool ValidateDataLength(uint8_t valueLen, const char* key, uint8_t dataLen)
{
    if (valueLen == 0) {
        NFCLOG_E("Get %s config failed, zero data length", key);
        return false;
    }

    if (valueLen > dataLen - 1) {
        NFCLOG_E("Get %s config failed, invalid data length: %u", key, valueLen);
        return false;
    }

    return true;
}

static bool ProcessBoolType(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_BOOL_TYPE || valueLen != sizeof(bool)) {
        NFCLOG_E("Invalid BOOL_TYPE length or null pointer for %s", item->key);
        return false;
    }
    *value = item->p_BOOL_TYPE;
    return true;
}

static bool ProcessUint8Type(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_UINT8_TYPE || valueLen != sizeof(uint8_t)) {
        NFCLOG_E("Invalid UINT8_TYPE length or null pointer for %s", item->key);
        return false;
    }
    *value = item->p_UINT8_TYPE;
    return true;
}

static bool ProcessUint16Type(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_UINT16_TYPE || valueLen != sizeof(uint16_t)) {
        NFCLOG_E("Invalid UINT16_TYPE length or null pointer for %s", item->key);
        return false;
    }
    *value = item->p_UINT16_TYPE;
    return true;
}

static bool ProcessUint32Type(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_UINT32_TYPE || valueLen != sizeof(uint32_t)) {
        NFCLOG_E("Invalid UINT32_TYPE length or null pointer for %s", item->key);
        return false;
    }
    *value = item->p_UINT32_TYPE;
    return true;
}

static bool ProcessStringType(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_STRING_TYPE) {
        NFCLOG_E("Null STRING_TYPE pointer for %s", item->key);
        return false;
    }

    if (!(*item->p_STRING_TYPE)) {
        *value = osi_calloc(valueLen + 1);
    } else if (valueLen > strlen((char*)*item->p_STRING_TYPE)) {
        osi_free(*item->p_STRING_TYPE);
        *item->p_STRING_TYPE = nullptr;
        *value = osi_calloc(valueLen + 1);
    } else {
        *value = *item->p_STRING_TYPE;
    }

    if (!*value) {
        NFCLOG_E("Malloc string length for %s failed", item->key);
        return false;
    }

    *item->p_STRING_TYPE = static_cast<char*>(*value);
    return true;
}

static bool ProcessArrayType(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    if (!item->p_ARRAY_TYPE) {
        NFCLOG_E("Null ARRAY_TYPE pointer for %s", item->key);
        return false;
    }

    if (!item->p_ARRAY_TYPE->inner_data) {
        *value = osi_calloc(valueLen);
    } else if (valueLen > item->p_ARRAY_TYPE->len) {
        osi_free(item->p_ARRAY_TYPE->inner_data);
        item->p_ARRAY_TYPE->inner_data = nullptr;
        *value = osi_calloc(valueLen);
    } else {
        *value = item->p_ARRAY_TYPE->inner_data;
    }

    if (!*value) {
        NFCLOG_E("Malloc %s array failed", item->key);
        return false;
    }

    item->p_ARRAY_TYPE->inner_data = static_cast<uint8_t*>(*value);
    item->p_ARRAY_TYPE->len = valueLen;
    return true;
}

static bool ProcessConfigValue(tNFC_CF_PARAM* item, uint8_t valueLen, void** value)
{
    switch (item->type) {
        case BOOL_TYPE:
            return ProcessBoolType(item, valueLen, value);

        case UINT8_TYPE:
            return ProcessUint8Type(item, valueLen, value);

        case UINT16_TYPE:
            return ProcessUint16Type(item, valueLen, value);

        case UINT32_TYPE:
            return ProcessUint32Type(item, valueLen, value);

        case STRING_TYPE:
            return ProcessStringType(item, valueLen, value);

        case ARRAY_TYPE:
            return ProcessArrayType(item, valueLen, value);

        default:
            NFCLOG_D("Not support config type: %d for %s", item->type, item->key);
            return false;
    }
}

static bool ProcessSingleConfigItem(tNFC_CF_PARAM* item, uint8_t* data, const uint8_t dataLen,
                                    const uint8_t outDataStartIdx)
{
    NFCLOG_D("Get %s", item->key);

    // 准备数据缓冲区
    if (!PrepareDataBuffer(data, dataLen, item)) {
        return false;
    }

    // 执行 IOCTL 调用
    if (tp_ioctl(IOCTL_GET_CONFIG_EXT, data) != NFC_STATUS_OK) {
        NFCLOG_E("tp_ioctl failed for %s", item->key);
        return false;
    }

    item->present = true;

    // 验证返回的数据长度
    uint8_t valueLen = data[outDataStartIdx];
    if (!ValidateDataLength(valueLen, item->key, dataLen)) {
        return false;
    }

    // 根据类型处理配置项
    void* value = nullptr;
    if (!ProcessConfigValue(item, valueLen, &value)) {
        NFCLOG_E("Get %s config value failed", item->key);
        return false;
    }

    // 复制数据到配置项目标位置
    if (!osi_memcpy(value, valueLen, data + outDataStartIdx + 1, valueLen)) {
        NFCLOG_E("Copy %s failed", item->key);
        return false;
    }

    return true;
}

tNFC_STATUS TransportAdaptation::GetExtConfig(tNFC_CONFIG_MANAGER *cm)
{
    OSI_CHK_PARAM_INVALID(!cm->vnd_ext_cf_table, return NFC_STATUS_FAILED);

    uint8_t data[IOCTL_RSP_BUF_SIZE] = {0};
    const uint8_t dataLen = 128;
    const uint8_t outDataStartIdx = 128;

    tNFC_CF_PARAM *vnd_ext_cf_table = static_cast<tNFC_CF_PARAM*>(cm->vnd_ext_cf_table);
    size_t table_len = cm->vnd_ext_cf_table_len;

    NFCLOG_I("Enter");

    for (size_t i = 0; i < table_len; ++i) {
        tNFC_CF_PARAM* item = &vnd_ext_cf_table[i];

        if (!item->key) {
            NFCLOG_E("Item key is null at index %zu", i);
            continue;
        }

        if (!ProcessSingleConfigItem(item, data, dataLen, outDataStartIdx)) {
            return NFC_STATUS_FAILED;
        }
    }

    return NFC_STATUS_OK;
}

tNFC_STATUS TransportAdaptation::GetConfig(tNFC_CONFIG_MANAGER *cm)
{
    tNFC_CF_PARAM *vnd_cf_table = static_cast<tNFC_CF_PARAM*>(cm->vnd_cf_table);
    size_t table_len = cm->vnd_cf_table_len;
    for (size_t i = 0; i < table_len; ++i) {
        /* 原生鸿蒙 config 的 present 默认为 true */
        vnd_cf_table[i].present = true;
    }
    return tp_get_vnd_config(&cm->cf.vendor_cf);
}

tNFC_STATUS TransportAdaptation::PowerCycle()
{
    if (mHal != nullptr) {
        NfcStatus status = NfcStatus::FAILED;
        int result = mHal->PowerCycle(status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("PowerCycle Succeeded");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

tNFC_STATUS TransportAdaptation::PreDiscovery()
{
    if (mHal != nullptr) {
        NfcStatus status = NfcStatus::FAILED;
        int result = mHal->Prediscover(status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Prediscover Succeeded");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

tNFC_STATUS TransportAdaptation::Write(const uint8_t* p_data, uint16_t dataLen)
{
    if (mHal != nullptr) {
        NfcStatus status = NfcStatus::FAILED;
        std::vector<uint8_t> data(p_data, p_data + dataLen / sizeof(uint8_t));
        int result = mHal->Write(data, status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Write Succeeded");
            return NFC_STATUS_OK;
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }
}

bool TransportAdaptation::IsConfigModified()
{
    NFCLOG_E("Enter");
    if (mHal == nullptr) {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return false;
    }

    uint8_t data[IOCTL_RSP_BUF_SIZE] = {0};
    uint8_t outDataStartIdx = 128;

    data[0] = FILE_TYPE_TMS;
    if (tp_ioctl(IOCTL_GET_CONFIG_MODIFIED_STATUS, data) != NFC_STATUS_OK) {
        NFCLOG_E("Failed to get tms config modified status!");
        return false;
    }

    if (data[outDataStartIdx] != 0) {
        NFCLOG_E("tms config has modifdied");
        return true;
    }

    data[0] = FILE_TYPE_RF;
    if (tp_ioctl(IOCTL_GET_CONFIG_MODIFIED_STATUS, data) != NFC_STATUS_OK) {
        NFCLOG_E("Failed to get rf config modified status!");
        return false;
    }

    if (data[outDataStartIdx] != 0) {
        NFCLOG_E("rf config has modifdied");
        return true;
    }

    return false;
}

void TransportAdaptation::InitializeHalService()
{
    mHal = INfcV1_1::Get();
    if (mHal == nullptr) {
        NFCLOG_E("INfc::getService Failed!");
    } else {
        auto devmgr = OHOS::HDI::DeviceManager::V1_0::IDeviceManager::Get();
        if (devmgr != nullptr) {
            NFCLOG_E("loadDevice of nfc HDF");
            devmgr->LoadDevice(NFC_HDI_NAME);
        }
        AddHdiDeathRecipient();
    }
}

void TransportAdaptation::RemoveHdiDeathRecipient()
{
    if (g_hdiService != nullptr) {
        HdfRemoteServiceRemoveDeathRecipient(g_hdiService, nullptr);
        g_hdiService = nullptr;
    }
}

void TransportAdaptation::AddHdiDeathRecipient()
{
    struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
    if (serviceMgr == nullptr) {
        NFCLOG_E("HDIServiceManagerGet failed");
        return;
    }
    g_hdiService = serviceMgr->GetService(serviceMgr, NFC_HDI_NAME);
    HDIServiceManagerRelease(serviceMgr);
    if (g_hdiService == nullptr) {
        NFCLOG_E("GetService g_hdiService failed");
        return;
    }
    static HdfDeathRecipient recipient = {
        .OnRemoteDied = [](HdfDeathRecipient *deathRecipient, HdfRemoteService *service) {
        RemoveHdiDeathRecipient();
        _exit(0);
        },
    };
    HdfRemoteServiceAddDeathRecipient(g_hdiService, &recipient);
    NFCLOG_I("Hdi service add death recipient success");
}

void TransportAdaptation::hal_check_firmware_callback(tNFC_EVENT event,
    __attribute__((unused)) tNFC_STATUS event_status)
{
    NFCLOG_I("hal_check_firmware_callback event=0x%X", event);
    switch (event) {
        case NFC_EVT_OPEN_CPLT: {
            NFCLOG_I("hal_check_firmware_callback OPEN_CPLT");
            if (osi_mutex_lock(&check_firmware_lock) != NFC_STATUS_OK) {
                NFCLOG_E("get check_firmware_lock failed");
            }
            if (event_status == NFC_STATUS_OK) is_check_firmware_completed = NFC_STATUS_OK;
            osi_mutex_notify(&check_firmware_lock);
            osi_mutex_unlock(&check_firmware_lock);
            break;
        }
        case NFC_EVT_CLOSE_CPLT: {
            NFCLOG_I("hal_check_firmware_callback CLOSE_CPLT");
            break;
        }
        default:
            break;
    }
}

void TransportAdaptation::hal_check_firmware_data_callback(__attribute__((unused))
    uint16_t dataLen, __attribute__((unused)) uint8_t* p_data) {}

tNFC_STATUS tp_get_vnd_config(tNFC_VENDOR_CONFIG *config)
{
    NFCLOG_I("enter");
    NfcStatus status = NfcStatus::FAILED;
    NfcVendorConfig configValue;
    if (mHal != nullptr) {
        int result = mHal->GetVendorConfig(configValue, status);
        if (result == HDF_SUCCESS && status == NfcStatus::OK) {
            NFCLOG_I("Succeeded with INfcHidl");
        } else {
            NFCLOG_E("Failed with result %d, status %d", result, static_cast<int32_t>(status));
            return NFC_STATUS_FAILED;
        }
    } else {
        NFCLOG_E("Failed to retrieve the NFC HAL!");
        return NFC_STATUS_FAILED;
    }

    config->nfa_poll_bailout_mode = configValue.pollBailOutMode ? 1 : 0;
    config->offhost_route = configValue.defaultOffHostRoute;
    config->offhost_route_felica = configValue.defaultOffHostRouteFelica;
    config->system_code_route = configValue.defaultSysCodeRoute;
    config->system_code_power_state = configValue.defaultSysCodePwrState;
    config->offhost_ese_pipe_id = configValue.esePipeId;
    config->offhost_sim_pipe_id = configValue.simPipeId;
    config->max_iso_dep_transceive_length = configValue.isoDepExtApduLength;
    config->host_allow_list.len = configValue.hostWhitelist.size();
    NFCLOG_D("host_allow_list.len = %zu", config->host_allow_list.len);
    if (config->host_allow_list.len > 0) {
        for (uint8_t i = 0; i < config->host_allow_list.len; ++i) {
            config->host_allow_list.inner_data[i] = configValue.hostWhitelist[i];
        }
    }
    config->offhost_route_uicc.len = configValue.offHostRouteUicc.size();
    NFCLOG_D("offhost_route_uicc.len = %zu", config->offhost_route_uicc.len);
    if (config->offhost_route_uicc.len > 0) {
        for (uint8_t i = 0; i < config->offhost_route_uicc.len; ++i) {
            config->offhost_route_uicc.inner_data[i] = configValue.offHostRouteUicc[i];
        }
    }
    config->offhost_route_ese.len = configValue.offHostRouteEse.size();
    NFCLOG_D("offhost_route_ese.len = %zu", config->offhost_route_ese.len);
    if (config->offhost_route_ese.len > 0) {
        for (uint8_t i = 0; i < config->offhost_route_ese.len; ++i) {
            config->offhost_route_ese.inner_data[i] = configValue.offHostRouteEse[i];
        }
    }
    config->iso_dep_route = configValue.defaultIsoDepRoute;
    NFCLOG_I("exit");
    return NFC_STATUS_OK;
}

void TransportAdaptation::Finalize()
{
    NFCLOG_I("Finalizing TransportAdaptation");
    if (mHal != nullptr) {
        mHal = nullptr;
    }
    if (mCallback != nullptr) {
        mCallback = nullptr;
    }
    instance.reset();
}

void PrintOhosLog(int logLevel, const char* fileName, const char* function, int line, const char* logMessage)
{
    if (logMessage == nullptr) {
        HILOG_ERROR(LOG_CORE, "%{public}s", "Failed to allocate memory for log message.");
        return;
    }
    if (nfc_log_is_debug_mode()) {
        /* 在调试模式下，输出文件名、函数名和行号 */
        switch (logLevel) {
            case LEVEL_DEBUG:
                HILOG_DEBUG(LOG_CORE, "[%{public}s(%{public}s:%{public}d)] %{public}s",
                    fileName, function, line, logMessage);
                break;
            case LEVEL_INFO:
                HILOG_INFO(LOG_CORE, "[%{public}s(%{public}s:%{public}d)] %{public}s",
                    fileName, function, line, logMessage);
                break;
            case LEVEL_WARN:
                HILOG_WARN(LOG_CORE, "[%{public}s(%{public}s:%{public}d)] %{public}s",
                    fileName, function, line, logMessage);
                break;
            case LEVEL_ERROR:
                HILOG_ERROR(LOG_CORE, "[%{public}s(%{public}s:%{public}d)] %{public}s",
                    fileName, function, line, logMessage);
                break;
            default:
                break;
        }
    } else {
        /* 非调试模式下，不输出额外的信息 */
        switch (logLevel) {
            case LEVEL_DEBUG:
                HILOG_DEBUG(LOG_CORE, "%{public}s", logMessage);
                break;
            case LEVEL_INFO:
                HILOG_INFO(LOG_CORE, "%{public}s", logMessage);
                break; \
            case LEVEL_WARN: \
                HILOG_WARN(LOG_CORE, "%{public}s", logMessage);
                break;
            case LEVEL_ERROR:
                HILOG_ERROR(LOG_CORE, "%{public}s", logMessage);
                break;
            default:
                break;
        }
    }
}
